package me.kuye.jkuye.core;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.kuye.jkuye.config.Constants;
import me.kuye.jkuye.config.JKuyeConfig;
import me.kuye.jkuye.handler.Handler;
import me.kuye.jkuye.log.Logger;

public class JKuyeFilter implements Filter {
	private JKuyeConfig jKuyeConfig;
	private static final JKuye instance = JKuye.getInstance();
	private static Logger logger;
	private Handler handler;
	private Constants constants;
	private String encoding;
	private int contextPathLength;

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		initConfig(filterConfig.getInitParameter("configClass"));
		if (instance.init(jKuyeConfig, filterConfig.getServletContext()) == false) {
			throw new RuntimeException("the config init error");
		}
		handler = instance.getHandler();
		constants = Config.getConstants();
		encoding = constants.getEncoding();
		jKuyeConfig.afterStart();
		String contextPath = filterConfig.getServletContext().getContextPath();
		contextPathLength = (contextPath == null || "/".equals(contextPath)) ? 0 : contextPath.length();
	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain)
			throws IOException, ServletException {
		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) resp;
		request.setCharacterEncoding(encoding);
		String target = request.getRequestURI();
		if (contextPathLength != 0) {
			target = target.substring(contextPathLength);
		}

		boolean[] isHandled = { false };
		try {
			handler.handle(target, request, response, isHandled);
		} catch (Exception e) {
			if (logger.isErrorEnabled()) {
				String qs = request.getQueryString();
				logger.error(qs == null ? target : target + "?" + qs, e);
			}
		}
		if (isHandled[0] == false) {
			filterChain.doFilter(request, response);
		}
	}

	@Override
	public void destroy() {
		jKuyeConfig.beforeStop();
		instance.stopPlugins();
	}

	/**
	 * @Description: 初始化config类 @param targetClass @return void @throws
	 */
	private void initConfig(String targetClass) {
		if (targetClass == null) {
			throw new RuntimeException("the config class is not exist");
		}
		Object configObject;
		try {
			configObject = Class.forName(targetClass).newInstance();
		} catch (Exception e) {
			throw new RuntimeException("can not create the config class instance " + targetClass, e);
		}

		if (configObject instanceof JKuyeConfig) {
			jKuyeConfig = (JKuyeConfig) configObject;
		} else {
			throw new RuntimeException("can not create the config class" + targetClass);
		}

	}

	public static void initLogger() {
		logger = Logger.getLogger(JKuyeFilter.class);
	}

}
